package com.navinfo.tripanalysis.service;

import com.navinfo.location.mileage.bean.MileageAndFuel;
import com.navinfo.tripanalysis.common.util.ArithmeticUtils;
import com.navinfo.tripanalysis.common.util.DateUtils;
import com.navinfo.tripanalysis.pojo.Point0F37;
import com.navinfo.tripanalysis.pojo.Point0200;
import com.navinfo.tripanalysis.pojo.Point;
import com.navinfo.tripanalysis.pojo.PreTripInfo;
import com.navinfo.tripanalysis.util.CommonUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 行程切分接口
 * @author web
 */
public interface PreTripInfoService {
    /**
     * 行程未开始
     */
    int TRIP_NO_START = 0;
    /**
     * 行程开始
     */
    int TRIP_START = 1;
    /**
     * 行程中
     */
    int TRIP_IN = 2;
    /**
     * 行程结束
     */
    int TRIP_END = 3;
    /**
     * 行程强制结束，两个位置点间隔大于FORCE_END_DURATION_THRESHOLD标记为强制结束
     */
    int TRIP_FORCE_END = 4;

    /**
     * 强制结束行程时长阀值：10分钟
     * 单位:MS
     */
    long FORCE_END_DURATION_THRESHOLD = 10 * 60  * 1000L;

    /**
     * 切分行程
     * @param points0f37
     * @param points0200
     * @param day 当前日期
     * @return
     */
    List<PreTripInfo> preJudgeTrip(List<Point> points0f37, List<Point0200> points0200, Date day);

    /**
     * 当前时间-上一个时间超过指定阀值，强制结束行程
     * @param lastGpsTime 上一个Point时间点
     * @param gpsTime      当前Point时间点
     * @return
     */
    default boolean isForceEnd(long lastGpsTime, long gpsTime) {
        return (gpsTime - lastGpsTime) > FORCE_END_DURATION_THRESHOLD;
    }

     /**
     * 行程结束的处理
     * @param points0f37
     * @param list
     * @param preTripInfo
     * @param status  为null时，为一天所有行程最后的状态处理
     * @param day
     */
     default void handleEnd(List<Point> points0f37, List<PreTripInfo> list, PreTripInfo preTripInfo, Integer status, Date day) {
        //没有行程信息直接返回
        if (preTripInfo == null) {
            return;
        }

        List<Point0200> subList0200 = preTripInfo.getSubPoints0200();

        //没有0200点信息直接返回
        if (CommonUtils.isCollectionEmpty(subList0200)) {
            return;
        }

        //一天最后一个点的gps时间（最大）
         Point0200 last0200 = subList0200.get(subList0200.size() - 1);
         long lastGpsTime = last0200.getGpsTime();
         preTripInfo.setEndTimeMs(lastGpsTime);
         preTripInfo.setEndLongitude(last0200.getLongitude());
         preTripInfo.setEndLatitude(last0200.getLatitude());
         preTripInfo.setEndHeight((int)last0200.getHeight());
         preTripInfo.setEndDirection(last0200.getDirection());


         //一天所有行程最后的状态处理
        if(status == null){
            status = isForceEnd(lastGpsTime, DateUtils.addDays(day, 1).getTime()) ? TRIP_FORCE_END : TRIP_END;
        }

        if (status == TRIP_FORCE_END) {
            preTripInfo.setForceEndFlag(1);
        } else {
            preTripInfo.setForceEndFlag(0);
        }

        //添加相关的0F37点
        if (CommonUtils.isCollectionNotEmpty(points0f37)) {
            preTripInfo.setSubPoints0f37(points0f37.stream()
            .filter(
                p -> (p.getGpsTime()>=preTripInfo.getStartTimeMs()) && (p.getGpsTime()<=preTripInfo.getEndTimeMs())
            ).map(p -> {
                ((Point0F37)p).setTripId(preTripInfo.getTripId());
                return p;
            }).collect(Collectors.toList()));
        }

        //根据0200点计算精准里程和精准油耗
        MileageAndFuel mileageAndFuel = CommonUtils.calcMileageFuel(subList0200);
        preTripInfo.setPreciseFuel(ArithmeticUtils.fuelLToMl(mileageAndFuel.getStdFuelCon()));
        preTripInfo.setPreciseMileage(ArithmeticUtils.mileageKMToM(mileageAndFuel.getStdMileage()));

        list.add(preTripInfo);
    }
}
